---@class Battle.ChainEffectGroup
local ChainEffectGroup = Battle.CreateClass("ChainEffectGroup")
Battle.ChainEffectGroup = ChainEffectGroup

function ChainEffectGroup:ctor(resName,sign)
    ---@type Battle.Entity[]
    self.actorList = {}
    ---@type Battle.ChainEffect[]
    self.chainList = {}
    self.resName = resName
    self.sign = sign
end
function ChainEffectGroup:OnDestroy()
    for k,v in pairs(self.actorList) do
        v.eventSystem:UnRegister(Battle.Event.ActorSignChange,self.SignChange,self)
        v.eventSystem:UnRegister(Battle.Event.ActorPosChanged,self.PosChanged,self)
    end
    for k,v in pairs(self.chainList) do
        v:OnDestroy()
        Battle.PoolMgr.ReturnEffectToPool(v)
    end
    self.actorList = nil
    self.chainList = nil
end
---@param actor Battle.Entity
function ChainEffectGroup:AddActor(actor)
    if table.ContainsValue(self.actorList,actor) then
        return
    end
    table.insert(self.actorList,actor)
    actor.eventSystem:Register(Battle.Event.ActorPosChanged,self.PosChanged,self)
    actor.eventSystem:Register(Battle.Event.ActorSignChange,self.SignChange,self)
end
---@param actor Battle.Entity
function ChainEffectGroup:RemoveActor(actor)
    actor.eventSystem:UnRegister(Battle.Event.ActorPosChanged,self.PosChanged,self)
    actor.eventSystem:UnRegister(Battle.Event.ActorSignChange,self.SignChange,self)

    table.RemoveValue(self.actorList,actor,true)
end

function ChainEffectGroup:Execute()
    local count = #self.actorList
    local chainCount = #self.chainList
    local need = count -1
    if chainCount > 0 and chainCount  > need then
        for i = 1,chainCount - need do
            local c = table.remove(self.chainList)
            Battle.EffectShowMgr.DestroyEffect(c)
        end
    end
    if chainCount < need then
        for i = 1,need - chainCount do
            local e = Battle.EffectFactory.CreateEffect(Battle.EffectType.BuffChain,self.resName)
            e:Execute()
            table.insert(self.chainList,e)
        end
    end
    self:PosChanged()
end
function ChainEffectGroup:PosChanged(args)
    for k,v in pairs(self.chainList) do
        v:Set(self.actorList[k].pos,self.actorList[k+1].pos)
    end
end
---@param args Battle.EntitySignChangeArgs
function ChainEffectGroup:SignChange(args)
    local sign = args.signId
    local actor = args.sender
    if sign ~= self.sign then return end
    if not args.isAdd then
        self:RemoveActor(actor)
        self:Execute()
    end
end